package com.example.axon.web;

import com.example.axon.AccountAggregate;
import com.example.axon.events.AccountBaseEvent;
import com.example.axon.utils.Protostuff;
import lombok.AllArgsConstructor;
import org.axonframework.config.ProcessingGroup;
import org.axonframework.eventhandling.EventHandler;
import org.axonframework.eventsourcing.EventSourcedAggregate;
import org.axonframework.eventsourcing.EventSourcingRepository;
import org.axonframework.messaging.Message;
import org.axonframework.messaging.interceptors.ExceptionHandler;
import org.axonframework.messaging.interceptors.MessageHandlerInterceptor;
import org.axonframework.modelling.command.LockAwareAggregate;
import org.springframework.stereotype.Component;

@Component
@AllArgsConstructor
@ProcessingGroup("SomeExceptionHandler")
public class SomeExceptionHandler {


    private final EventSourcingRepository<AccountAggregate> accountAggregateRepository;

    private final AccountRepository accountRepository;

    @EventHandler
    public void on(AccountBaseEvent event) {

        AccountAggregate aggregateRoot = accountAggregateRepository.load(event.getAccountId())
                .getWrappedAggregate()
                .getAggregateRoot();

        AccountEntity accountEntity = accountRepository.getAccountEntityByAccountId(event.getAccountId())
                .orElseGet(AccountEntity::new);

        AccountEntity updated = Protostuff.lombokBuilder(accountEntity, AccountEntity.AccountEntityBuilder.class)
                .accountId(aggregateRoot.getId())
                .userName(aggregateRoot.getUserName())
                .password(aggregateRoot.getPassword())
                .deposit(aggregateRoot.getBalance())
                .build();

        accountRepository.save(updated);
    }



    @MessageHandlerInterceptor
    public void intercept(Message<?> message) {

        System.out.println("SomeExceptionHandler.intercept");
        // Add your intercepting logic here based on the
//        throw new RuntimeException("hello");
    }


    /**
     *
     * annotation  {@link ExceptionHandler} only work in single projection?
     * @see SomeExceptionHandler
     */
    @ExceptionHandler
    public void handle(Exception exception) {
        System.out.println("SomeExceptionHandler.handle");
    }
}